package cn.fetosoft.woodpecker.controller;

import cn.fetosoft.woodpecker.core.data.entity.BaseElement;
import cn.fetosoft.woodpecker.core.data.form.ElementForm;
import cn.fetosoft.woodpecker.core.data.service.ElementService;
import cn.fetosoft.woodpecker.core.enums.DateFormatEnum;
import cn.fetosoft.woodpecker.core.enums.ElementCategory;
import cn.fetosoft.woodpecker.core.util.MenuTree;
import cn.fetosoft.woodpecker.core.util.RandomUtil;
import cn.fetosoft.woodpecker.core.util.UploadFile;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author guobingbing
 * @version 1.0
 * @wechat t_gbinb
 * @create 2021/6/10 9:27
 */
@Slf4j
@RestController
@RequestMapping(value = "/auth/common", produces = "application/json")
public class CommonController extends BaseController {

	@Autowired
	private ElementService elementService;

	/**
	 * 构建菜单树
	 * @return
	 */
	@RequestMapping("/getMenuTree")
	public String getMenuTree(){
		List<MenuTree> rootList = new ArrayList<>();
		ElementForm planForm = new ElementForm();
		planForm.setRows(0);
		try{
			List<BaseElement> elementList = elementService.selectListByForm(planForm, BaseElement.class);
			if(CollectionUtils.isEmpty(elementList)){
				return JSON.toJSONString(rootList);
			}
			List<BaseElement> planList = elementList.stream().filter(e -> "testPlan".equals(e.getCategory()))
					.sorted(Comparator.comparingInt(BaseElement::getSort)).collect(Collectors.toList());
			for(int i=0; i<planList.size(); i++){
				BaseElement p = planList.get(i);
				MenuTree planNode = this.createChildNode(i, planList);
				this.recursionTree(planNode, elementList);
				planNode.setState("closed");
				rootList.add(planNode);
			}
		}catch(Exception e){
			log.error("getMenuTree", e);
		}
		return JSON.toJSONString(rootList);
	}

	private void recursionTree(MenuTree parent, List<BaseElement> list){
		List<BaseElement> children = list.stream().filter(e-> e.getParentId().equals(parent.getId()))
		 		.sorted(Comparator.comparingInt(BaseElement::getSort))
				.collect(Collectors.toList());
		if(children.size()>0){
			for(int i=0; i<children.size(); i++){
				MenuTree childTree = this.createChildNode(i, children);
				recursionTree(childTree, list);
				parent.setState("closed");
				parent.addChild(childTree);
			}
		}
	}

	private MenuTree createChildNode(int counter, List<BaseElement> children){
		BaseElement element = children.get(counter);
		BaseElement before = null;
		if(counter>0){
			before = children.get(counter-1);
		}
		BaseElement after = null;
		if(counter<(children.size()-1)){
			after = children.get(counter+1);
		}
		MenuTree childTree = this.createChildNode(element, before, after);
		return childTree;
	}

	/**
	 * 获取节点的子树
	 * @param id
	 * @return
	 */
	@RequestMapping("/getChildTree")
	public String getChildTree(@RequestParam String id, @RequestParam String beforeId){
		BaseElement root = (BaseElement) elementService.findById(id, BaseElement.class);
		BaseElement beforeElement = (BaseElement) elementService.findById(beforeId, BaseElement.class);
		MenuTree tree = this.createChildNode(root, beforeElement, null);
		try{
			this.recursionChildTree(tree);
		}catch(Exception e){
			log.error("getChildTree", e);
		}
		return JSON.toJSONString(tree);
	}

	/**
	 * 查询测试片段
	 * @return
	 */
	@RequestMapping("/getTestFragment")
	public String getTestFragment(@RequestParam String id){
		List<MenuTree> rootList = new ArrayList<>();
		BaseElement element = (BaseElement)elementService.findById(id, BaseElement.class);
		if(element!=null){
			ElementForm planForm = new ElementForm();
			planForm.setRows(0);
			planForm.setPlanId(element.getPlanId());
			planForm.setCategory(ElementCategory.TEST_FRAGMENT.getName());
			try {
				List<BaseElement> elementList = elementService.selectListByForm(planForm, BaseElement.class);
				if(!CollectionUtils.isEmpty(elementList)){
					for(BaseElement el : elementList){
						MenuTree childTree = new MenuTree(el.getId(), el.getName(), el.getCategory());
						childTree.setPlanId(el.getPlanId());
						rootList.add(childTree);
					}
				}
			} catch (Exception e) {
				log.error("getTestFragment", e);
			}
		}
		return JSON.toJSONString(rootList);
	}

	/**
	 * 文件上传
	 * @param file
	 * @param planId
	 * @return
	 */
	@PostMapping("/upload")
	public String upload(@RequestParam("file") MultipartFile file, @RequestParam String planId){
		Result<UploadFile> result = Result.errorResult();
		try{
			String saveDir = System.getProperty("user.dir") + File.separator + "jmeter" + File.separator + planId;
			File dir = new File(saveDir);
			if (!dir.exists()) {
				boolean b = dir.mkdirs();
				if(!b){
					result.setErrorMsg("上传目录没有写入权限");
					return result.toString();
				}
			}
			String saveFileName = DateFormatEnum.YMDHMS.dateToString(new Date()) + RandomUtil.getRandomNumChar(8);
			long size = file.getSize()/1024/1024;
			if(size>30){
				result.setErrorMsg("文件不能超过30M");
				return result.toString();
			}
			String fileName = file.getOriginalFilename();
			String format = "";
			if (fileName.lastIndexOf(".") > 0) {
				format = fileName.substring(fileName.lastIndexOf("."));
			}
			String savePath = saveDir + File.separator + saveFileName + format;
			UploadFile uploadFile = new UploadFile();
			uploadFile.setName(fileName);
			uploadFile.setExtension(format);
			uploadFile.setAbsolutePath(savePath);

			file.transferTo(new File(savePath));
			result.setStatus(Result.SUCCESS);
			result.setObj(uploadFile);
		}catch(Exception e){
			result.setErrorMsg("文件上传失败");
			log.error("upload", e);
		}
		return result.toString();
	}
}
